/*
 * CUdevService.h
 *
 *  Created on: 6 Jul, 2013
 *      Author: root
 */

#ifndef CUDEVSERVICE_H_
#define CUDEVSERVICE_H_
#ifndef _WIN32
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/vfs.h>
#include <linux/netlink.h>

#include <sys/mount.h>
#include <dirent.h>
#endif
//#include "CThread.h"
#include <map>
#include <string>
using namespace std;

#include "crossplat_def.h"
#define UEVENT_MSG_LEN 4096
/*一个U盘上最多的分区个数*/
#define MAX_USBPARTITION_NUM    5
/*U盘设备文件名的最大长度*/
#define MAX_USBDEVNAME_LEN    80
/*最多可能存在的U盘数目*/
#define MAX_USBNUM				4

#define MAX_UDEV	4	//sda,sdb,sdc,目前最多支持4个udev

struct UdevEventPara
{
    const char *action;
	const char *devName;
	const char *devType;
	int partNumber;
    int major;
    int minor;
};



//基本原理，一个挂载目录对应到一个磁盘分区 比较/mnt/disk/00/data01
struct uDevInfo
{
	char mountPoint[64];	//挂载路径
	char deviceText[40];	//设备描述符
	char devName[16];		//设备名 /dev/sda
	int  partNo;
	long long totalSize;	//Byte
	long long freeSpace;	//Byte
	bool bMount ;			//
	int udevStatus;			//0-正常挂载,可读写;1-正常挂载,不可读写;2-未格式化;3-正常卸载
};

typedef map<string,uDevInfo>  MAP_USBDisk_INFO; // partition , UdevInfo
typedef map<string,string>    MAP_MNT_INFO;

class CUdevService
{
public:;
	CUdevService();
	virtual ~CUdevService();

public:
	int startService();
	static void *entry(void *param);
	int body();
	bool LoadMountInfo();
	static void *MountUsbThreadEntry(void *param);
	int MountUsbThreadBody(bool bDetect = false);
    int CallBackUsbDiskInfo();
	int GetMountInfo();
	int GetUSBDiskFreeSize(char * device);
	int callBackUMountInfo(char *path);
	int UnMountDevPartition(char * device= NULL);
	int UnMountDeviceInfo(char * device);
	int  ClearDirOfDevice(char * device);
	bool IsBeInclude(char * device);

	int GetUDevProcess()
	{
		return m_procStep;
	}
	MAP_USBDisk_INFO* GetUsbDiskMp()
	{
		return &m_mpDiskInfo;
	}
	enum CHECK_STATUS
	{
		UDEV_CHK_NORMAL = 0,
		UDEV_CHK_ADD_DISK,
		UDEV_CHK_ADD_PARTITION,
		UDEV_CHK_REMOVE_DISK,
		UDEV_CHK_REMOVE_PARTITION,
	};
	//检测处理流程
	enum CHECK_PROCESS
	{
		UDEV_PROC_WAITEVENT        = 0, //等待接收事件
		UDEV_PROC_EVENTPARSE_START = 1, //解析开始。
		UDEV_PROC_EVENTPARSE_END   = 2, //解析结束。
		UDEV_PROC_ADD_DISK         = 3, //添加磁盘
		UDEV_PROC_ADD_PART         = 4, //添加磁盘分区
		UDEV_PROC_REMOVE_DISK      = 5, //移除磁盘分区
		UDEV_PROC_CLEAR_DIR        = 6, //清除当前磁盘的无效目录
	};
protected:

	bool MakeDirectory(const char *directory);
	int initHotplugSock(void);
	int handleEventParse(const char *msg,struct UdevEventPara* pUEvent);
	int getUdiskState(long long* pFreeSpace, long long* pTotalSpace, char *path);

	int callBackMountInfo(char *path, struct uDevInfo & devInfo);
	int callBackUnformatInfo(char *path,struct uDevInfo & devInfo);

	int ClearInvalidDir();
	int MountDiskNonePart(const char * device,int fsType);

private:
	int infoUpload(void *buf, int length);

protected:
	CCross_Lock mInfoLock;
	cross_thread_t m_dataThdID;
	MAP_USBDisk_INFO m_mpDiskInfo;
	int        m_procStep; // USB 检测流程
};

extern CUdevService g_usbDetected;

#endif /* CUDEVSERVICE_H_ */


